#include <cByteStream.h>
#include <cstddef>
#include <cstring>
#include <string.h>
#include <cstdarg>

namespace mdk
{
    enum BufType
    {
        FREAM_BUFFER = 0,
        MALLOC_BUFFER = 1
    };

    CByteBuffer::CByteBuffer()
    {
        Init(Stackm_len);
    }

    CByteBuffer::CByteBuffer(int nCapacityIn)
    {
        Init(nCapacityIn, MALLOC_BUFFER);
    }

    CByteBuffer::~CByteBuffer()
    {
        if (m_type == MALLOC_BUFFER)
            delete[] m_lpBuf;
        m_lpBuf = NULL;
    }

    void CByteBuffer::GetMoreCapacity(int len)
    {
        int tatolLen = m_capacity;
        while ((m_curLen + len) > tatolLen)
        {
            tatolLen <<= 1;
        }

        if (tatolLen != m_capacity)
        {
            BYTE *pBytesMore = new BYTE[tatolLen];
            if (pBytesMore == nullptr)
            {
                m_isOk = false;
            }
            else
            {
                memset(pBytesMore, 0x00, m_capacity);
                memcpy(pBytesMore, m_lpBuf, m_curLen);
                if (m_type == MALLOC_BUFFER)
                    delete[] m_lpBuf;
                m_type = MALLOC_BUFFER;
                m_lpBuf = pBytesMore;
                m_capacity = tatolLen;
            }
        }
    }

    void CByteBuffer::Init(int nCapatityIn, int type)
    {
        m_capacity = nCapatityIn;
        m_curLen = 0;
        m_position = 0;
        m_isOk = true;
        m_type = type;
        m_count = 0;
        if (type == MALLOC_BUFFER)
            m_lpBuf = new BYTE[nCapatityIn];
        else
            m_lpBuf = m_cbuf;
        memset(m_lpBuf, 0x00, m_capacity);
    }
    void CByteBuffer::ReSet()
    {
        m_curLen = 0;
        m_position = 0;
        m_isOk = 0;
        m_count = 0;
        memset(m_lpBuf, 0, m_capacity);
    }
    CByteBuffer &CByteBuffer::Append(char *buf, int len)
    {
        if (buf != nullptr && len > 0)
        {
            GetMoreCapacity(len);
            memcpy(m_lpBuf + m_curLen, buf, len);
            m_curLen += len;
        }
        return *this;
    }
    CByteBuffer &CByteBuffer::Append(char *buf)
    {
        return Append(buf, strlen(buf));
    }
    CByteBuffer &CByteBuffer::Extract(char *buf, int len, int begin)
    {

        begin = (begin <= 0 ? m_position : begin);
        int tatolLen = m_curLen - begin;
        int nlen = tatolLen > len ? len : tatolLen;

        if (buf == nullptr)
            return *this;

        (void)memcpy(buf, m_cbuf + begin, nlen);
        return *this;
    }
    CByteBuffer &CByteBuffer::Read(char *buf, int len)
    {

        Extract(buf, len, m_position);
        if (m_curLen > (m_position + len))
            m_position += len;
        else
            m_position = m_curLen;

        return *this;
    }
}